﻿function isServer() return triggerClientEvent ~= nil end
function isClient() return triggerServerEvent ~= nil end
function getScriptLocation() return isServer() and "Server" or "Client"	end

if getScriptLocation() == "Client" then
	-- Start Client
	
	function string:split(sSeparator, nMax, bRegexp)
		assert(sSeparator ~= '')
		assert(nMax == nil or nMax >= 1)
		local aRecord = {}
		if self:len() > 0 then
			local bPlain = not bRegexp
			nMax = nMax or -1
			local nField=1 nStart=1
			local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
			while nFirst and nMax ~= 0 do
				aRecord[nField] = self:sub(nStart, nFirst-1)
				nField = nField+1
				nStart = nLast+1
				nFirst,nLast = self:find(sSeparator, nStart, bPlain)
				nMax = nMax-1
			end
			aRecord[nField] = self:sub(nStart)
		end
		return aRecord
	end

	function isHexCodes ( str, start )
		local chars = { ["0"] = true, ["1"] = true, ["2"] = true, ["3"] = true, ["4"] = true, 
						["5"] = true, ["6"] = true, ["7"] = true, ["8"] = true, ["9"] = true,
						["A"] = true, ["B"] = true, ["C"] = true, ["D"] = true, ["E"] = true, ["F"] = true,
						["a"] = true, ["b"] = true, ["c"] = true, ["d"] = true, ["e"] = true, ["f"] = true }
		local ifound = 0
		for i = start, #str do
			if ( utfSub ( str, start - 1, start - 1 ) == "#" ) then
				local hex = utfSub ( str, i, i )
				if ( chars [ hex ] == true ) then
					ifound = ifound + 1
					if ( ifound == 6 ) then
						return true
					end
				elseif ( hex == " " or not chars [ hex ] or chars [ hex ] == nil ) then
					return false
				end
			else
				return false
			end
		end
		return false
	end

	local _dxDrawText = dxDrawText
	function dxDrawText ( text, x, y, colors, scale, font, alignX, alignY, wordBreak, colored )
		if ( #text ~= 0 ) then
			if ( not colors ) then
				colors = tocolor(255, 255, 255, 255)
			end

			if ( string.find ( text, "\n" ) ) then
			
				local i = {}
				local h = {}
				local xx = {}
				local yy = {}
				
				if ( alignY ) then
					local nl = 0
					for lines, _ in next, string.split ( text, "\n" ) do
						nl = nl + 1
					end
					
					if ( alignY == "center" ) then
						y = y - ( nl * dxGetFontHeight ( scale , font ) ) / 2
					elseif ( alignY == "bottom" ) then
						y = y - ( nl * dxGetFontHeight ( scale , font ) )
					end
				end
				
				for ii, v in next, string.split ( text, "\n" ) do
					
					i[ii] = 0
					h[ii] = 0
					
					xx[ii] = x
					yy[ii] = y + ( ii - 1 ) * dxGetFontHeight ( scale , font )
					
					if ( alignX ) then
						local newtext = v
						if ( colored ) then
							newtext = newtext : gsub ( "#%x%x%x%x%x%x", "" )
						end
						newtext = newtext : gsub ( "\n", "" )
						
						if ( alignX == "center" ) then
							xx[ii] = x - dxGetTextWidth ( newtext, scale, font ) / 2
						elseif ( alignX == "right" ) then
							xx[ii] = x - dxGetTextWidth ( newtext, scale, font )
						end
					end
					
					while i[ii] <= #v do
					
						if ( colored and utfSub ( v, i[ii], i[ii] ) == "#" and isHexCodes ( v, i[ii] + 1 ) ) then
							local hred   = utfSub ( v, i[ii] + 1, i[ii] + 2 )
							local hgreen = utfSub ( v, i[ii] + 3, i[ii] + 4 )
							local hblue  = utfSub ( v, i[ii] + 5, i[ii] + 6 )
							local halpha = string.format ( "%08X", colors ) : sub ( 1, 2 )
							
							colors = tocolor ( getColorFromString ( "#" .. hred .. hgreen .. hblue .. halpha ) )
							i[ii] = i[ii] + 7
						end
					
						_dxDrawText ( utfSub ( v, i[ii], i[ii] ), xx[ii] + h[ii], yy[ii], xx[ii] + h[ii], yy[ii], colors, scale, font, "left", "top", false, false, postGUI )
						h[ii] = h[ii] + dxGetTextWidth ( utfSub ( v, i[ii], i[ii] ), scale, font )
						i[ii] = i[ii] + 1
					end
				end
			else
				local i = 0
				local h = 0
			
				if ( alignX ) then
					local newtext = text
					if ( colored ) then
						newtext = newtext : gsub ( "#%x%x%x%x%x%x", "" )
					end
					
					if ( alignX == "center" ) then
						x = x - dxGetTextWidth ( newtext, scale, font ) / 2
					elseif ( alignX == "right" ) then
						x = x - dxGetTextWidth ( newtext, scale, font )
					end
				end
				
				if ( alignY ) then				
					if ( alignY == "center" ) then
						y = y - dxGetFontHeight ( scale , font ) / 2
					elseif ( alignY == "bottom" ) then
						y = y - dxGetFontHeight ( scale , font )
					end
				end
				
				while i <= #text do
				
					if ( colored and utfSub ( text, i, i ) == "#" and isHexCodes ( text, i + 1 ) ) then
						hred   = utfSub ( text, i + 1, i + 2 )
						hgreen = utfSub ( text, i + 3, i + 4 )
						hblue  = utfSub ( text, i + 5, i + 6 )
						halpha = string.format ( "%08X", colors ) : sub ( 1, 2 )
						
						colors = tocolor ( getColorFromString ( "#" .. hred .. hgreen .. hblue .. halpha ) )
						i = i + 7
					end
					_dxDrawText ( utfSub ( text, i, i ), x + h, y, x + h, y, colors, scale, font, "left", "top", false, false, postGUI )
					h = h + dxGetTextWidth ( utfSub ( text, i, i ), scale, font )
					i = i + 1
				end
			end
		end
	end

	function dxDrawText3D ( text, x, y, z, distance, colors, scale, font, alignX, alignY )
		local px, py, pz = getElementPosition ( getLocalPlayer ( ) )
		local distance2 = getDistanceBetweenPoints3D ( px, py, pz, x, y, z )
		if ( distance2 <= distance ) then
			local sx, sy = getScreenFromWorldPosition ( x, y, z, scale )
			if ( not sx ) or ( not sy ) then return end
			
			scale = scale * ( ( distance - distance2 ) / distance )
			
			dxDrawText ( text, sx, sy, colors, scale, font, alignX, alignY )
		end
	end
	-- End Client
end

function math.lerp ( from, to, alpha )
    return from + ( to - from ) * alpha
end

function math.evalCurve ( curve, input )
	if input < curve[1][1] then
		return curve[1][2]
	end
	for idx=2, #curve do
		if input<curve[idx][1] then
			local x1 = curve[idx-1][1]
			local y1 = curve[idx-1][2]
			local x2 = curve[idx][1]
			local y2 = curve[idx][2]
			local alpha = (input - x1)/(x2 - x1);
			return math.lerp(y1,y2,alpha)
		end
	end
	return curve[#curve][2]
end

function getPointFromDistanceRotation ( x, y, dist, angle )
	local a = math.rad ( 90 - angle )
	local dx = math.cos ( a ) * dist
	local dy = math.sin ( a ) * dist
	return x + dx, y + dy
end

function findRotation ( x1, y1, x2, y2 )
	local t = - math.deg ( math.atan2( x2 - x1, y2 - y1 ) )
	if t < 0 then t = t + 360 end
	return t
end

function isPointInTriangle ( x, y, x1, y1, x2, y2, x3, y3 )
    if sign(x, y, x1, y1, x2, y2) < 0 or
        sign(x, y, x2, y2, x3, y3) < 0 or
        sign(x, y, x3, y3, x1, y1) < 0
    then
        return false
    end
    return true
end
 
function sign ( x1, y1, x2, y2, x3, y3 )
    return ( x1 - x3 ) * ( y2 - y3 ) - ( x2 - x3 ) * ( y1 - y3 )
end